<template>
  <div class="custom-tree">
    <div v-for="node in treeData" :key="node.id" class="tree-node" :class="{ 'tree-node-expanded': node.expanded }">
      <div class="tree-node-label">
        <el-icon v-if="node.children && node.children.length > 0" @click="handleNodeClick(node)">
          <CaretRight :class="!node.expanded ? 'icon-caret-right' : 'icon-caret-bottom'" />
        </el-icon>
        <el-checkbox v-if="avaChecked" v-model="node.checked" @change="handleCheckChange(node)"
          :disabled="node.disabled" :indeterminate="node.indeterminate"></el-checkbox>
        <span @click="handleNodeClick(node)" class="tree-node-label-text">{{ node.label
          }}</span>

        <!-- 添加自定义内容 -->
        <div class="tree-node-custom-content">
          <slot name="treeOperation" :node="node">
            <!-- 在父组件中使用，比如el-form -->
            <!-- <el-form>
            <el-form-item label="数据权限:">
              <el-select v-model="dataScope" placeholder="请选择" clearable style="width: 50%;">
                <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-form> -->
          </slot>
        </div>
      </div>


      <div v-if="node.expanded && node.children && node.children.length > 0" class="tree-node-children">
        <CustomTree :treeData="node.children" :avaChecked="props.avaChecked" @node-checked="handleChildCheckChange"
          :class="node.isLast ? 'tree-node-last' : ''" />
      </div>


    </div>
  </div>
</template>

<script lang="ts" setup name="CustomTree">
import { ref, watch, PropType } from 'vue';
import { ElCheckbox } from 'element-plus';




interface TreeNode {
  id: number;
  label: string;
  expanded: boolean;
  checked: boolean;
  disabled: boolean;
  indeterminate: boolean; // 新增属性
  parentId: number; // 新增属性
  children?: TreeNode[];
  buttonPermissionDtoList?: any[];
  isLast: boolean
}

const props = defineProps({
  treeData: {
    type: Array as PropType<TreeNode[]>,
    required: true,
  },
  avaChecked: {  //激活多选Tree选择器
    type: Boolean,
    default: false
  },
  alleExpanded: {  //全部展开
    type: Boolean,
    default: false
  },
  allChecked: {
    type: Boolean,
    default: false
  },
  dataScopeValue: {
    type: Number,
    default: 0
  }
});


const dataScope = ref<any>()
const options = [
  {
    value: 1,
    label: '全部'
  },
  {
    value: 2,
    label: '所属部门'
  },
  {
    value: 3,
    label: '所属部门及下级部门'
  },
  {
    value: 4,
    label: '全部数据'
  },
  {
    value: 5,
    label: '指定单位/部门'
  }
]
// watch(() => props.dataScopeValue, (newValue) => {
//   // 如果有值，则每一个节点赋值 dataScope
//   dataScope.value = newValue;
//   updateTreeDataScope(props.treeData, newValue);
// });

// // 更新树节点的 dataScope 值
// const updateTreeDataScope = (nodes: TreeNode[], dataScopeValue: any) => {
//   nodes.forEach(node => {
//     node.dataScope = dataScopeValue;
//     if (node.children) {
//       updateTreeDataScope(node.children, dataScopeValue);
//     }
//   });
// };


const emit = defineEmits(['node-checked', 'node-click']);

const toggleNode = (node: TreeNode) => {
  node.expanded = !node.expanded;
};

const handleCheckChange = (node: TreeNode) => {
  updateChildCheckStatus(node);
  updateParentCheckStatus(node);
  emit('node-checked', node);
};

const handleChildCheckChange = (node: TreeNode) => {
  updateParentCheckStatus(node);
  emit('node-checked', node);
};

//点击节点触发事件
const handleNodeClick = (node: TreeNode) => {
  toggleNode(node);
  emit('node-click', node);
};

// 更新子节点选中状态
const updateChildCheckStatus = (node: TreeNode) => {

  if (node.children) {
    node.children.forEach(child => {
      child.checked = node.checked;
      child.indeterminate = false; // 清除子节点的 indeterminate 状态
      updateChildCheckStatus(child);
    });
  }
};


// 更新父节点选中状态
const updateParentCheckStatus = (node: TreeNode) => {
  const parentNode = findParentNode(node);
  if (parentNode) {
    const allChecked = parentNode.children?.every(child => child.checked) || false;
    const someChecked = parentNode.children?.some(child => child.checked || child.indeterminate) || false;

    parentNode.checked = allChecked;
    parentNode.indeterminate = someChecked && !allChecked;

    updateParentCheckStatus(parentNode);
  }
};


// 根据节点 ID 查找查找全部上级node
const findParentNode = (node: TreeNode): TreeNode | undefined => {
  const findNodeById = (nodes: TreeNode[], id: number): TreeNode | undefined => {
    for (const n of nodes) {
      if (n.id === id) return n;
      if (n.children) {
        const found = findNodeById(n.children, id);
        if (found) return found;
      }
    }
    return undefined;
  };

  return findNodeById(props.treeData, node.parentId);
};

//全部选中
const selectAll = () => {
  if (props.allChecked) {
    selectNode(props.treeData);
  }
};
const selectNode = (nodes: TreeNode[]) => {
  nodes.forEach(node => {
    node.checked = true;
    if (node.children) {
      selectNode(node.children);
    }
  });
};
//全部不选
const unSelectAll = () => {
  if (!props.allChecked) {
    unSelectNode(props.treeData);
  }
};
const unSelectNode = (nodes: TreeNode[]) => {
  nodes.forEach(node => {
    node.checked = false;
    if (node.children) {
      unSelectNode(node.children);
    }
  });
};
watch(() => props.allChecked, (newValue) => {
  selectAll();
  unSelectAll()
});

//全部展开
const expandAll = () => {
  if (props.alleExpanded) {
    expandNode(props.treeData);
  }
};
const expandNode = (nodes: TreeNode[]) => {
  nodes.forEach(node => {
    node.expanded = true;
    if (node.children) {
      expandNode(node.children);
    }
  });
};

//全部收起
const collapseAll = () => {
  if (!props.alleExpanded) {
    collapseNode(props.treeData);
  }
};
const collapseNode = (nodes: TreeNode[]) => {
  nodes.forEach(node => {
    node.expanded = false;
    if (node.children) {
      collapseNode(node.children);
    }
  });
};

watch(() => props.alleExpanded, (newValue) => {
  expandAll();
  collapseAll()
});


// 判断是否为最后一个节点
const isLastNode = (node: TreeNode) => {
  // Find the last node in the tree
  const findLastNode = (nodes: TreeNode[]): TreeNode | null => {
    if (!nodes || nodes.length === 0) return null;
    const lastNode = nodes[nodes.length - 1];
    if (lastNode.children && lastNode.children.length > 0) {
      return findLastNode(lastNode.children);
    }
    return lastNode;
  };

  const lastNode = findLastNode(props.treeData);
  return lastNode && lastNode.id === node.id;
};

defineExpose({
  selectAll,
  expandAll,
  unSelectAll,
  collapseAll
})

</script>

<style scoped>
.custom-tree {
  width: 100%;
}

.tree-node-last {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
}

.tree-node {
  margin-left: 1rem;
}

.tree-node-label {
  display: flex;
  align-items: center;
  cursor: pointer;
}

.tree-node-children {
  margin-left: 1rem;
}

.tree-node-custom-content {
  margin-left: 1rem;
}

.tree-node-label-text {
  margin-left: 10px;
}

.icon-caret-right {
  color: #acafb6;
  margin-right: 4px;
}

.icon-caret-bottom {
  color: #acafb6;
  transform: rotate(90deg);
  margin-right: 4px;
}
</style>
